<?php

/**
 * Description of x10_StateManager_StateProvider
 *
 * @author prometheus
 */
class x10_StateManager_StateProvider extends x10_Provider
{
	public $xName = 'Rendszerállapot-szolgáltató: ';

	public $name = '';

	public $path = '';

	public $loaderStack = array();

	/**
	 * @var x10_StateManager_State
	 */
	protected $state;

	protected $isActive = FALSE;

	/**
	 * Konstruktor.
	 * Létrehozza az állapotot reprezentáló objektumot a config alapján.
	 * @param x10_Config $config
	 * @throws E_Provider_ConfigNotExists
	 * @throws E_Provider_ConfigParseError
	 */
	public function __construct(x10_Config $config)
	{
		parent::__construct($config);

		$this->name = $this->config->getConfigKey('name');
		$this->path = x10::$systemRoot.$this->config->getConfigKey('path');

		$this->xName .= $this->name;
		$this->state = new x10_StateManager_State(
			$this->name,
			$this->path,
			$this->config->getConfigKey('classesLoaded'),
			$this->config->getConfigKey('classes')
		);
	}

	/**
	 * Visszatér a kezelt rendszerállapot objektummal.
	 * @return x10_StateManager_State
	 */
	public function get()
	{
		return $this->state;
	}

	/**
	 * Regisztrálja az állapot kezeléséhez szükséges automatikus osztály
	 * betöltő metódust
	 * (lásd: {@link http://php.net/spl_autoload_register spl_autoload_register()}.
	 * @return Bool
	 */
	public function activate()
	{
		$this->isActive = spl_autoload_register(array($this, 'autoLoadHandler'));
		$this->state->loadClasses();
		return $this->isActive;
	}

	/**
	 * Leiratja a korábban regisztrált automatikus osztály betöltő metódust.
	 * (lásd: {@link http://php.net/spl_autoload_unregister spl_autoload_unregister()}.
	 * @return Bool
	 */
	public function deactivate()
	{
		if ($this->isActive)
		{
			$this->isActive = !spl_autoload_unregister(array($this, 'autoLoadHandler'));
		}
		return !$this->isActive;
	}

	/**
	 * Az állapot-szolgáltató akkor tekinthető aktívnak, ha kezelni tudja az
	 * alatta elérni kívánt osztályokat (képes automatikusan betölteni ezeket).
	 * Amennyiben ez megvalósul, a visszatérés TRUE lesz, ellenkező esetben FALSE.
	 * @return Bool
	 */
	public function isActive()
	{
		return $this->isActive;
	}

	public function autoLoadHandler($className)
	{
		$nsMan = x10::dedicate('x10_NamespaceManager');
		// Névtér ellenőrzés - a rendszerhez tartozik-e az osztály?
		if ($nsMan->getNamespaceFor($className) !== FALSE)
		{
			// rekurzív betöltési sorrend kezelése veremmel.
			array_push($this->loaderStack, $className);
			require($this->state->classes->appendQueue($className)->classPath);
			array_pop($this->loaderStack);

			// a rekurzió végén a verem üres, a betöltött osztályokat regisztrálni kell
			if (count($this->loaderStack) == 0)
			{
				$this->state->classes->mapQueueReverse();
			}
		}
	}
}

?>